﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.DataVisualization.Charting;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Blame;
using Blame.Entity;
using Ookii.Dialogs.Wpf;
using System.Windows.Forms;
using MessageBox = System.Windows.MessageBox;

namespace BlameUI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private FolderBrowserDialog _oldFolderDialog = new FolderBrowserDialog();
        private VistaFolderBrowserDialog vistafolderDialog = new VistaFolderBrowserDialog();
        private Controller _controller;
        private IEnumerable<User> _users;
        private User selectedUser;

        private BackgroundWorker _backgroundWorker;

        public MainWindow()
        {
            this.InitializeComponent();

            _controller = new Controller();
            _backgroundWorker = new BackgroundWorker();
            _backgroundWorker.DoWork +=new DoWorkEventHandler(_backgroundWorker_DoWork);
            _backgroundWorker.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);

            InitializeFolderDialogs();

            resetUI();
        }

        void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            changeUserSelection();
        }

        void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Cancelled)
            {
                //cancelled
            } else if(e.Error != null)
            {
                // exception thrown
            } else
            {
                // completed
            }
        }

        private void InitializeFolderDialogs()
        {
            const string dialogDescription = "Please select a repo folder";
            vistafolderDialog.Description = dialogDescription;
            vistafolderDialog.UseDescriptionForTitle = true;
            // This applies to the Vista style dialog only, not the old dialog.
            vistafolderDialog.ShowNewFolderButton = true;
            _oldFolderDialog.Description = dialogDescription;
            _oldFolderDialog.ShowNewFolderButton = true;
        }

        private string SelectPath()
        {
            string path = "";

            if (VistaFolderBrowserDialog.IsVistaFolderDialogSupported)
            {
                if ((bool)vistafolderDialog.ShowDialog())
                {
                    path = vistafolderDialog.SelectedPath;
                }
            }
            else
            {
                DialogResult result = _oldFolderDialog.ShowDialog();

                if (result == System.Windows.Forms.DialogResult.OK)
                {
                    path = _oldFolderDialog.SelectedPath;
                }
            }

            return path;
        }

        private void BrowseBtn_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            PathTxtBox.Text = SelectPath();
        }

        private void ConnectBtn_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            resetUI();

            try
            {
                if (PathTxtBox.Text != "")
                {
                    _controller.ConnectToRepo(PathTxtBox.Text);
                    _users = _controller.GetUsers();
                    List<string> userList = new List<string>();

                    foreach (User u in _users)
                    {
                        userList.Add(u.Name + " <" + u.Email + ">");
                    }

                    this.UserListBox.ItemsSource = userList;

                    int totalAddRemovePC;
                    int totalAddPC;
                    int totalRemovePC;
                    int totalAddRemovePL;
                    int totalAddPL;
                    int totalRemovePL;

                    _controller.GetChurnStatisticsByChangesets(out totalAddRemovePC, out totalAddPC, out totalRemovePC);
                    _controller.GetChurnStatisticsByLines(out totalAddRemovePL, out totalAddPL, out totalRemovePL);

                    this.ProjectChangesetsTxtBlock.Text = "Total Add/Remove: "
                                                          + totalAddRemovePC + "\nTotal Add: " + totalAddPC + " (" + Math.Round(100.0 * totalAddPC / totalAddRemovePC, 2)
                                                          + "%)" +
                                                          "\nTotal Remove: " +
                                                          totalRemovePC + " (" + Math.Round(100.0 * totalRemovePC / totalAddRemovePC, 2)
                                                          + "%)";
                    this.ProjectLinesTxtBlock.Text = "Total Add/Remove: "
                        + totalAddRemovePL + "\nTotal Add: " + totalAddPL + " (" + Math.Round(100.0 * totalAddPL / totalAddRemovePL, 2)
                                                          + "%)" + "\nTotal Remove: " +
                                                      totalRemovePL + " (" + Math.Round(100.0 * totalRemovePL / totalAddRemovePL, 2)
                                                          + "%)";

                    MessageBox.Show("Repository connected successfully");
                }
            }
            catch (System.IO.DirectoryNotFoundException)
            {
                MessageBox.Show("Could not connect to repo");
            }
        }

        private void resetUI()
        {
            BtnChangeset.Visibility = Visibility.Hidden;
            LinesChart.Visibility = Visibility.Hidden;
            ChangesetsChart.Visibility = Visibility.Hidden;
            this.UserListBox.ItemsSource = null;
            this.LinesTxtBlock.Text = "";
            this.ChangesetsTxtBlock.Text = "";
            this.ProjectChangesetsTxtBlock.Text = "";
            this.ProjectLinesTxtBlock.Text = "";
        }

        private void UserListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            _backgroundWorker.RunWorkerAsync();
        }

        private void changeUserSelection()
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                // iterate to get user

                IEnumerator<User> iter = _users.GetEnumerator();

                selectedUser = iter.Current;

                for (int i = 0; i <= UserListBox.SelectedIndex; i++)
                {
                    iter.MoveNext();
                    selectedUser = iter.Current;
                }

                if (selectedUser != null)
                {
                    int totalAddRemoveC;
                    int totalAddC;
                    int totalRemoveC;
                    int totalAddRemoveL;
                    int totalAddL;
                    int totalRemoveL;

                    ChurnInfo changeset = _controller.GetUserContributionByChangesets(selectedUser, out totalAddRemoveC, out totalAddC, out totalRemoveC);
                    ChurnInfo lines = _controller.GetUserContributionByLines(selectedUser, out totalAddRemoveL, out totalAddL, out totalRemoveL);

                    this.LinesTxtBlock.Text = "Total Add/Remove: "
                                                      + lines.UserAddRemoveCount + "\nTotal Add: " + lines.UserAddCount + " (" + Math.Round(100.0 * lines.UserAddCount / lines.UserAddRemoveCount, 2)
                                                          + "%)" + "\nTotal Remove: " +
                                                      lines.UserRemoveCount + " (" + Math.Round(100.0 * lines.UserRemoveCount / lines.UserAddRemoveCount, 2)
                                                          + "%)";

                    this.ChangesetsTxtBlock.Text = "Total Add/Remove: "
                                                      + changeset.UserAddRemoveCount + "\nTotal Add: " + changeset.UserAddCount + " (" + Math.Round(100.0 * changeset.UserAddCount / changeset.UserAddRemoveCount, 2)
                                                          + "%)" + "\nTotal Remove: " +
                                                      changeset.UserRemoveCount + " (" + Math.Round(100.0 * changeset.UserRemoveCount / changeset.UserAddRemoveCount, 2)
                                                          + "%)";

                    LoadLinesPieChartData(lines.UserAddRemoveCount, totalAddRemoveL);
                    LoadChangesetsPieChartData(changeset.UserAddRemoveCount, totalAddRemoveC);
                    BtnChangeset.Content = "View " + selectedUser.Name + "'s Changesets";
                    BtnChangeset.Visibility = Visibility.Visible;
                }
            }), System.Windows.Threading.DispatcherPriority.Normal);
        }

        private void LoadLinesPieChartData(int usertotal, int grouptotal)
        {
            LinesChart.Visibility = Visibility.Visible;
            ((PieSeries)LinesChart.Series[0]).ItemsSource =
                new KeyValuePair<string, int>[]{
            new KeyValuePair<string, int>("User", usertotal),
            new KeyValuePair<string, int>("Others", grouptotal - usertotal) };
        }

        private void LoadChangesetsPieChartData(int usertotal, int grouptotal)
        {
            ChangesetsChart.Visibility = Visibility.Visible;
            ((PieSeries)ChangesetsChart.Series[0]).ItemsSource =
                new KeyValuePair<string, int>[]{
            new KeyValuePair<string, int>("User", usertotal),
            new KeyValuePair<string, int>("Others", grouptotal - usertotal) };
        }

        private void BtnChangeset_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if(selectedUser != null)
            {
                ChangesetWindow cw = new ChangesetWindow(selectedUser, _controller);
                cw.ShowDialog();    
            }
        }



        public class Contribution
        {
            public string User { get; set; }
            public int Changeset { get; set; }
        }
    }
}